/********************************************************************************
 * Project Name		[JavaSE_Fundamentals]
 * File Name     	[AnnotationNotes.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package jdk5.annotation._notes;

/**
 * Annotation笔记
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public final class AnnotationNotes {

	public void annotationConcept() {
		/**
		 * 1. annotation[注解], 是一种安全的类似注释的机制, 用来将任何的信息或元数据[metadata]与程序元素[类, 方法,
		 * 成员变量等]进行关联 <br/>
		 * 2. annotation是一个接口<br/>
		 * 3. annotation像一种修饰符一样, 应用于包, 类型, 构造方法, 方法, 成员变量, 参数及本地变量的声明语句中<br/>
		 * 4. annotation不能影响程序代码的执行, 无论增加, 删除annotation, 代码都始终如一的执行<br/>
		 * 5. annotation通过java的反射API方法在运行时被访问<br/>
		 * 6. annotation被Java虚拟机忽略, 因此这些annotation在代码中是无作用的<br/>
		 * 7. annotation被Java编译器用某种特殊的方式处理<br/>
		 * 
		 * 程序可以通过反射来获取指定程序元素的annotation对象, 然后通过annotation对象来获取注解里面的元数据<br/>
		 */

		/**
		 * annotation的成员在annotation类型中以无参数的方法的形式被声明, 其方法名和返回值定义了该成员的名字和类型<br/>
		 * 1. annotation的方法必须是无参数, 无异常抛出的<br/>
		 * 2. annotation的方法名即为annotation的成员名<br/>
		 * 3. annotation的方法的返回值为annotation成员的类型<br/>
		 * 4. annotation成员的类型只能为primitive类型, String类型, Class类型, 枚举类型,
		 * annotation类型或者由前面类型之一作为元素的一维数组<br/>
		 * 5. annotation方法后可以使用 default和一个默认数值来声明成员的默认值, null不能作为成员默认值<br/>
		 * 6. annotation的成员不能使用泛型[除了返回值类型为Class]<br/>
		 */
	}

	public void metadata() {
		/**
		 * 元数据[MetaData]: 关于数据的数据<br/>
		 * 
		 * 功能<br/>
		 * 1. 编写文档: 通过代码里标识的元数据生成文档<br/>
		 * 2. 代码分析: 通过代码里标识的元数据对代码进行分析<br/>
		 * 3. 编译检查: 通过代码里标识的元数据让编译器能实现基本的编译检查<br/>
		 * 
		 * Java中的元数据<br/>
		 * 1. 元数据以标签的形式存在于Java代码中<br/>
		 * 2. 元数据描述的信息是类型安全的, 即元数据内部的字段都是有明确类型的<br/>
		 * 3. 元数据需要编译器之外的工具额外的处理用来生成其它的程序部件<br/>
		 * 4. 元数据可以只存在于Java源代码级别, 也可以存在于编译之后的class文件内部<br/>
		 * 5. 元数据的存在并不影响程序代码的编译和执行, 它只是被用来生成其它的文件或在运行时知道被运行代码的描述信息<br/>
		 */
	}

	public void annotationType() {
		/**
		 * 根据注解参数的个数, 可以将注解分为三类<br/>
		 * 1. 标记注解: 无成员定义的, 其仅使用自身的存在与否来为我们提供信息, 如@Override<br/>
		 * 2. 单值注解<br/>
		 * 3. 完整注解<br/>
		 * 
		 * 根据注解使用方法和用途, 可以将注解分为三类<br/>
		 * 1. jdk内置系统注解<br/>
		 * 2. 元注解<br/>
		 * 3. 自定义注解<br/>
		 */
	}

	public void systemAnnotations() {
		/**
		 * 系统注解<br/>
		 * 
		 * 1. @Override: 限定重写父类方法<br/>
		 * a. 该注解是一个标记注解类型, 被用作标注方法<br/>
		 * b. 该注解说明了被标注的方法重载了父类的方法, 起到了断言的作用<br/>
		 * c. 使用了这种注解在一个没有覆盖父类方法的方法时, Java编译器将以一个编译错误来警示<br/>
		 * d. 使用@Override时要在被修饰的方法前面加上即可<br/>
		 * 
		 * 2. @Deprecated:标记已过时<br/>
		 * a. 该注解是一个标记注解类型, 被用作标记包, 类/接口, 方法, 构造方法, 属性, 局部变量, 参数<br/>
		 * b .当一个类型或者类型成员使用@Deprecated修饰, 其表示编译器将不鼓励使用这个被标注的程序元素<br/>
		 * c. 并且这种修饰具有一定的 "延续性": 如果在代码中通过继承或者覆盖的方式使用了这个过时的类型或者成员,
		 * 虽然继承或者覆盖后的类型或者成员并不是被声明为 @Deprecated, 但编译器仍然要报警<br/>
		 * d. @Deprecated 注解类型和JavaDoc中的 @deprecated 这个tag是有区别的:<br/>
		 * 前者是Java编译器识别的, 而后者是被JavaDoc工具所识别用来生成文档[包含程序成员为什么已经过时,
		 * 该注解应当如何被禁止或者替代的描述], 推荐使用前者<br/>
		 * 
		 * 3. @SuppressWarnings:压制警告<br/>
		 * a. 被用作标记类/接口, 构造方法, 方法, 属性, 局部变量, 参数<br/>
		 * b. 该注解有一个类型为String[]的成员, 该成员取值为被禁止的警告名[被-Xlint选项有效的警告名],
		 * 同时编译器忽略掉无法识别的警告名<br/>
		 * c. annotation语法允许在annotation名后跟括号,
		 * 括号中是使用逗号分割的name=value对用于为annotation的成员赋值<br/>
		 * d. 常见的取值<br/>
		 * ---unchecked: 未检查的类型转换<br/>
		 * ---rawtypes: 未使用泛型约束集合<br/>
		 * ---unused: 变量/方法未使用<br/>
		 * ---serial: 可序列化的类缺少serialVersionUID<br/>
		 * ---deprecation: 使用了过时的类或方法<br/>
		 * ---fallthrough: switch程序块缺少break语句<br/>
		 * ---path: 类路径/源文件路径不存在<br/>
		 * ---finally: 任何finally语句不能正常完成时<br/>
		 * ---all: 关于以上所有情况的警告<br/>
		 */
	}

	public void metaAnnotation() {
		/**
		 * 元注解: 负责解释其他注解的注解<br/>
		 * 
		 * 1. @Target 用于描述注解的使用范围[被描述的注解可以用在什么地方]<br/>
		 * 取值[ElementType]<br/>
		 * PACKAGE: 包<br/>
		 * TYPE: 类, 接口, 枚举<br/>
		 * FIELD: 属性<br/>
		 * CONSTRUCTOR: 构造器<br/>
		 * METHOD: 方法<br/>
		 * OARAMETER: 方法参数<br/>
		 * LOCAL_VARIABLE: 局部变量<br/>
		 * 
		 * 2. @Retention 用于描述该annotation被保留多久<br/>
		 * 取值[RetentionPolicy]<br/>
		 * SOURCE: 注解保留在源文件中<br/>
		 * CLASS: 注解保留在class文件中<br/>
		 * RUNTIME: 注解在运行时有效<br/>
		 * 
		 * 3. @Documented 用于其他类型的annotation,
		 * 表示被标注的注解可以被JavaDoc记录[默认JavaDoc不包括注解]<br/>
		 * 该注解为标记注解<br/>
		 * 
		 * 4. @Inherited 如果一个使用了 @Inherited 修饰的注解类型被用于一个class,
		 * 则这个annotation将被用于该class的子类<br/>
		 * 该注解为标记注解<br/>
		 * 当被 @Inherited 修饰的注解类型的Retention类型是RetentionPolicy.RUNTIME,
		 * 通过反射API会检查class和其父类, 直到发现指定的注解或到达类机构的顶层
		 */
	}

	public void definedAnnotation() {
		/**
		 * 自定义注解<br/>
		 * 
		 * <code>
		 * public @interface AnnotationName { 
		 *     // ...... 
		 * }
		 * </code>
		 * 
		 * 注解参数的可支持数据类型<br/>
		 * 1. 基本数据类型[byte, short, int, long, float, double, char, boolean] <br/>
		 * 2. String类型<br/>
		 * 3. Class类型<br/>
		 * 4. enum类型<br/>
		 * 5. Annotation类型<br/>
		 * 6. 以上所有类型的一维数组<br/>
		 * 
		 * 注解可使用的修饰符: public或default<br/>
		 * 
		 * 注解元素必须有确定的值, 要么在定义时指定默认值, 要么使用时指定<br/>
		 * 非基本类型的注解元素不能为null, 使用""或0作为默认值<br/>
		 */
	}

	public void handleAnnotation() {
		/**
		 * 处理annotation的一些方法<br/>
		 * 
		 * 当一个annotation的 @Retention 为Runtime时, 该注解才能在运行时可见<br/>
		 * 
		 * <T extends Annotation> T getAnnotation(Class<T> annotationClass);
		 * 返回调用类上存在的, 指定类型的注解, 若不存在则返回null<br/>
		 * 
		 * Annotation[] getAnnotations(); 返回调用类上存在的所有注解<br/>
		 * 
		 * boolean isAnnotationPresent(Class<? extends Annotation>
		 * annotationClass); 判断调用类上是否存在指定类型的注解, 存在返回true, 否则返回false<br/>
		 * 
		 * Annotation[] getDeclaredAnnotations(); 返回调用类上存在的所有注解, 但会略继承的注解
		 */
	}
}
